# cron: 16 6 * * *
# new Env("熊猫代理更换白名单")
import requests
import os
import sys
import time
from datetime import datetime
import warnings
from urllib3.exceptions import InsecureRequestWarning

# 禁用SSL警告
warnings.filterwarnings("ignore", category=InsecureRequestWarning)

# ================= 配置区 =================
API_KEY = os.getenv('API_KEY_XM')
if not API_KEY:
    print("错误：未找到API_KEY_XM环境变量")
    sys.exit(1)

ORDER_NO = "GL20250504011107IYcSiPHq"
BASE_URL = "http://www.xiongmaodaili.com/xiongmao-web"
IP_SERVICES = [
    {'url': 'http://ifconfig.me/ip', 'verify': False},
    {'url': 'http://ip.3322.net', 'verify': False},
    {'url': 'http://myip.ipip.net', 'verify': False}
]
MAX_RETRIES = 3
REQUEST_DELAY = 2
# ==========================================

def debug_log(msg, level="INFO"):
    """分级日志系统"""
    timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    color_code = {
        "DEBUG": "\033[94m",   # 蓝色
        "INFO": "\033[92m",    # 绿色
        "WARNING": "\033[93m", # 黄色
        "ERROR": "\033[91m",   # 红色
        "SYSTEM": "\033[95m"   # 紫色
    }.get(level, "\033[0m")
    print(f"{color_code}## [{timestamp}] [{level}] {msg}\033[0m")

def get_public_ip():
    """获取公网IP"""
    debug_log("正在获取公网IP...", "DEBUG")
    for service in IP_SERVICES:
        try:
            response = requests.get(service['url'], timeout=5, verify=service['verify'])
            if response.status_code == 200:
                ip = response.text.strip()
                if validate_ip(ip):
                    debug_log(f"验证通过的公网IP：{ip}", "SUCCESS")
                    return ip
        except Exception as e:
            debug_log(f"{service['url']}查询失败：{str(e)}", "DEBUG")
    debug_log("所有IP服务不可用", "ERROR")
    return None

def validate_ip(ip):
    """IP地址格式验证"""
    parts = ip.split('.')
    return len(parts) == 4 and all(0 <= int(part) < 256 for part in parts)

def get_whitelist():
    """获取当前白名单列表（适配新接口格式）"""
    url = f"{BASE_URL}/clientWhilteList/listUserIp"
    params = {'secret': API_KEY}
    
    try:
        response = requests.get(url, params=params, timeout=10)
        debug_log(f"原始响应内容：{response.text}", "DEBUG")
        
        data = response.json()
        # 修复点1：正确解析状态码
        if str(data.get('code')) == '0' and data.get('errno') == 0:
            # 修复点2：从obj字段获取数据
            ip_list = [item['ip'] for item in data.get('obj', []) if 'ip' in item]
            debug_log(f"获取到{len(ip_list)}个白名单IP", "SUCCESS")
            return ip_list
            
        error_msg = data.get('msg') or '未知错误'
        debug_log(f"接口错误：{error_msg}（状态码：{data.get('code')}）", "ERROR")
    except Exception as e:
        debug_log(f"请求白名单接口失败：{str(e)}", "ERROR")
    return None

def replace_oldest_ip(old_ip, new_ip):
    """更换最早添加的IP（带时间戳验证）"""
    url = f"{BASE_URL}/whilteList/addOrUpdate"
    params = {
        'orderNo': ORDER_NO,
        'secret': API_KEY,
        'oldIp': old_ip,
        'newIp': new_ip
    }
    
    debug_log(f"正在更换IP：{old_ip} → {new_ip}", "INFO")
    try:
        response = requests.get(url, params=params, timeout=15)
        debug_log(f"更换接口原始响应：{response.text}", "DEBUG")
        
        data = response.json()
        if str(data.get('code')) == '0':
            debug_log("IP更换成功", "SUCCESS")
            return True
            
        error_msg = data.get('msg') or '未知错误'
        debug_log(f"更换失败：{error_msg}（状态码：{data.get('code')}）", "ERROR")
    except Exception as e:
        debug_log(f"请求更换接口失败：{str(e)}", "ERROR")
    return False

def get_oldest_ip(ip_list):
    """根据接口返回数据获取最早添加的IP（需要真实接口数据验证）"""
    # 注意：实际应根据update_time字段排序，但接口未返回完整时间戳数据
    # 这里暂时返回列表第一个IP作为示例
    return ip_list[0] if ip_list else None

def main():
    debug_log("===== 熊猫代理白名单管理 =====", "SYSTEM")
    
    # 第一步：获取当前公网IP
    public_ip = get_public_ip()
    if not public_ip:
        debug_log("无法获取有效公网IP", "FATAL")
        sys.exit(1)
    
    # 第二步：获取白名单（带重试）
    whitelist = None
    for _ in range(MAX_RETRIES):
        whitelist = get_whitelist()
        if whitelist:
            break
        time.sleep(REQUEST_DELAY)
    else:
        debug_log("连续3次获取白名单失败", "FATAL")
        sys.exit(1)
    
    # 判断是否需要处理
    if public_ip in whitelist:
        debug_log("当前IP已在白名单中，无需操作", "SUCCESS")
        sys.exit(0)
    
    debug_log("当前IP不在白名单中，开始更换流程...", "WARNING")
    
    # 第三步：获取最早添加的IP
    oldest_ip = get_oldest_ip(whitelist)
    if not oldest_ip:
        debug_log("无法确定需要更换的旧IP", "FATAL")
        sys.exit(1)
    debug_log(f"找到待更换的旧IP：{oldest_ip}", "INFO")
    
    # 第四步：执行更换
    if not replace_oldest_ip(oldest_ip, public_ip):
        debug_log("IP更换失败", "FATAL")
        sys.exit(1)
    
    # 第五步：最终验证
    debug_log("等待接口数据刷新...", "SYSTEM")
    time.sleep(10)  # 等待服务器刷新
    
    final_list = get_whitelist()
    if not final_list:
        debug_log("最终验证失败：无法获取最新白名单", "FATAL")
        sys.exit(1)
        
    if public_ip in final_list:
        debug_log(f"最终验证通过：{public_ip} 已生效", "SUCCESS")
    else:
        debug_log(f"最终验证失败：当前白名单为 {final_list}", "FATAL")
        sys.exit(1)
    
    debug_log("===== 操作成功完成 =====", "SYSTEM")

if __name__ == '__main__':
    main()